import sys
import os
from datetime import date, datetime
sys.path.append(os.path.dirname(os.path.dirname(__file__)))

from tqsdk import TqApi, TqAuth, TqSim, TqBacktest, BacktestFinished
from strategies.wq101_zscore_strategy import WQ101ZscoreStrategy
from utils.config_manager import ConfigManager
from utils.strategy_recorder import StrategyDBRecorder

# 使用项目根目录的.settings
project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
config = ConfigManager(config_dir=os.path.join(project_root, '.settings'))
account_config = config.get_account_config('tqsdk_account')

# 初始化数据库记录器
db_recorder = StrategyDBRecorder(db_path="trading_backtest.db")

# 回测参数
start_date = date(2022, 1, 1)
end_date = date(2024, 12, 31)
init_balance = 10000000
start_time = datetime.now()

symbol_info = {
    "m": {
        "exchange": "DCE",
        # Alpha 因子参数（20个因子）
        "alpha001_period": 5,
        "alpha002_period": 10,
        "alpha003_period": 10,
        "alpha006_period": 10,
        "alpha011_period": 5,
        "alpha020_period": 5,
        "alpha023_period": 20,
        "alpha027_period": 10,
        "alpha030_month": 20,
        "alpha030_year": 240,
        "alpha032_period": 20,
        "alpha041_period": 10,
        "alpha045_period": 10,
        # alpha053: 只需2根K线，无需配置
        "alpha057_period": 10,
        "alpha065_period": 5,
        "alpha081_period": 20,
        "alpha084_period": 20,
        "alpha093_period": 20,
        "alpha094_period": 5,
        # alpha101: 只需当前K线，无需配置
        # Z-score 参数（拉长窗口）
        "zscore_window": 300,  # Z-score 计算窗口（300天，约1年多）
        "max_series_length": 800,  # 最大保存序列长度
        # Tanh 映射参数（控制仓位敏感度）
        "tanh_scale": 1.0,  # 缩放系数：1.0=标准敏感度，>1.0=更敏感，<1.0=更平滑
    }
}

sim = TqSim(init_balance=init_balance)
api = TqApi(
    account=sim,
    backtest=TqBacktest(start_dt=start_date, end_dt=end_date),
    auth=TqAuth(account_config['user_id'], account_config['password']),
    web_gui="http://127.0.0.1:2017"
)

strategy = WQ101ZscoreStrategy(api, symbol_info, market_period=24*60)  # 日线

try:
    strategy.on_bar()
except BacktestFinished:
    end_time = datetime.now()
    run_duration = (end_time - start_time).total_seconds()
    
    # 获取账户信息和统计数据
    account = api.get_account()
    tqsdk_stats = getattr(account, '_tqsdk_stat', None)
    trade_log = getattr(sim, 'trade_log', None)
    
    # 打印回测结果
    print(f"\n{'='*60}")
    print(f"WQ101 Z-score 策略回测结果（20因子+连续仓位）")
    print(f"{'='*60}")
    print(f"初始资金: {init_balance:,.0f}")
    print(f"最终资金: {account.balance:,.0f}")
    print(f"收益率: {(account.balance - init_balance) / init_balance:.2%}")
    print(f"运行时长: {run_duration:.2f} 秒")
    print(f"{'='*60}")
    
    # 保存回测结果到数据库
    backtest_id = db_recorder.save_backtest_result(
        strategy_name=strategy.strategy_name,
        symbol=",".join(symbol_info.keys()),
        start_date=start_date.strftime('%Y-%m-%d'),
        end_date=end_date.strftime('%Y-%m-%d'),
        init_balance=init_balance,
        final_balance=account.balance,
        tqsdk_stats=tqsdk_stats,
        run_duration=run_duration,
        strategy_params=symbol_info,
        test_timestamp=datetime.now().isoformat()
    )
    
    # 保存交易日志到数据库
    trade_count = 0
    if trade_log:
        trade_count = db_recorder.save_trade_logs(backtest_id, trade_log)
        print(f"已保存 {trade_count} 条交易记录到数据库")
    
    print(f"回测结果已保存到数据库，ID: {backtest_id}")
    
    api.wait_update()
    api.close()
